package com.hotel.BL;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import com.EntityName;
import com.Util;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.FlexiblePackage;
import data.GuestType;

public class FlexiblePackageLogic extends AbstractBL{
	public FlexiblePackage GetFlexiblePackage(long id) {
		Key key = KeyFactory.createKey(EntityName.FlexiblePackage, id);
		try {
			Entity lang = datastore.get(key);
			FlexiblePackage c = new FlexiblePackage();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	public FlexiblePackage GetFlexiblePackage(Entity entity) {
		FlexiblePackage item = new FlexiblePackage();
		item.setEntity(entity);
		return item;
	}
	
	public List<FlexiblePackage> GetList(List<Entity> entities) {
		List<FlexiblePackage> list = new ArrayList<FlexiblePackage>();
		if(entities!=null)
		for (Entity e : entities) {
			FlexiblePackage a = new FlexiblePackage();
			a.setEntity(e);
			list.add(a);
		}
		return list;
	}
	
	public FlexiblePackage AddFlexiblePackage(long hotelId,String availableForString,
			boolean status,Date datefrom,Date dateto,String description,String packageName,
			String roomtypeString,String subflexiblepackage)
			throws EntityNotFoundException {
		FlexiblePackage t = new FlexiblePackage();
		t.setAvaliableForString(availableForString);
		t.setPackageControl(status);
		t.setDatefrom(datefrom);
		t.setDateto(dateto);
		t.setDescription(description);
		t.setHotelId(hotelId);
		t.setPackageName(packageName);
		t.setRoomtypeString(roomtypeString);
		t.setSubflexiblepackagestring(subflexiblepackage);
		t.setStatus(true);
		t.setAvaliable(true);
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);
		return t;
	}
	
	public String GetSubFlexiblePackageString(Date datefrom,Date dateto,
			String ppnArray,String ucpArray,String extrabedArray,String adultArray,String childArray,
			String breakfastArray,String dateArray) throws EntityNotFoundException, ParseException{
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd",
				Locale.ENGLISH);
		long span = Util.daysBetween(datefrom, dateto);
		String subflexiblepackagestring = "";
		String [] date = dateArray.split(",");
		String [] ppn = ppnArray.split(",");
		String [] ucp = ucpArray.split(",");
		String [] extrabed =extrabedArray.split(",");
		String [] adult =adultArray.split(",");
		String [] child =childArray.split(",");
		String [] breakfast =breakfastArray.split(",");
		for(int i=0;i<span;i++){
			Date dates = formatter.parse(date[i]);
			long subfpid = new SubFlexiblePackageLogic().AddSubFlexiblePackage(dates, 
					Double.parseDouble(extrabed[i]), Double.parseDouble(ppn[i]), 
					Double.parseDouble(ucp[i]),Long.parseLong(adult[i]),Long.parseLong(child[i]),
					Boolean.parseBoolean(breakfast[i])).getId();
			subflexiblepackagestring += subfpid + ",";
		}
		return subflexiblepackagestring.substring(0, subflexiblepackagestring.length()-1);
	}
	
	public FlexiblePackage UpdateFlexiblePackage(FlexiblePackage fpackage)
	{
		Key key = datastore.put(fpackage.getEntity());
		fpackage.setId(key.getId());
		fpackage.setKey(key);
		return fpackage;
	}
	
	public List<FlexiblePackage> GetAllFlexiblePackage4AdminLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.FlexiblePackage);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filterArchive = new FilterPredicate("isArchive",FilterOperator.EQUAL,false);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable,filterArchive);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset)));
	}	
	
	public List<FlexiblePackage> GetAllFlexiblePackageArchive4AdminLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.FlexiblePackage);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filterArchive = new FilterPredicate("isArchive",FilterOperator.EQUAL,true);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable,filterArchive);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset)));
	}
	public List<FlexiblePackage> GetAllFlexiblePackage4Admin(long hotelId)
	{
		Query q = new Query(EntityName.FlexiblePackage);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filterArchive = new FilterPredicate("isArchive",FilterOperator.EQUAL,false);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable,filterArchive);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public List<FlexiblePackage> GetAllFlexiblePackageArchive4Admin(long hotelId)
	{
		Query q = new Query(EntityName.FlexiblePackage);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filterArchive = new FilterPredicate("isArchive",FilterOperator.EQUAL,true);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable,filterArchive);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}	
	public FlexiblePackage ChangeStatus(long id) throws EntityNotFoundException{
		
		FlexiblePackage a = GetFlexiblePackage(id);	
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		 
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public FlexiblePackage DeleteFlexiblePackage(long id) throws EntityNotFoundException{
		
		FlexiblePackage a = GetFlexiblePackage(id);
		a.setAvaliable(false);
		a.setStatus(false);
		
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public FlexiblePackage ChangeArchivedLogic(long id) throws EntityNotFoundException{
		FlexiblePackage a = GetFlexiblePackage(id);
		a.setArchive(!a.isArchive());
		a.setStatus(!a.isStatus());
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public HashMap<String, Object> ChangeFormatForEditFlexiblePackage(FlexiblePackage flex){
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("id", flex.getId());
		map.put("PackageName", flex.getPackageName());
		map.put("RoomType", flex.getRoomtypeString());
		map.put("Description", flex.getDescription());
		map.put("AvaliableFor", ToAvaliableList(flex.getAvaliableFor()));
		map.put("From", flex.getDatefrom());
		map.put("To", flex.getDateto());
		map.put("SubPackage", flex.getSubflexiblepackage());
		map.put("PackageControl", flex.isPackageControl());
		return map;
	}
	
	public List<Long> ToAvaliableList(List<GuestType> list){
		List<Long> ans = new ArrayList<Long>();
		for(int i=0;i<list.size();i++){
			ans.add(list.get(i).getId());
		}
		return ans;
	}
	
	public String EditSubFlexiblePackageString(String pIdArray,Date datefrom,Date dateto,
			String ppnArray,String ucpArray,String extrabedArray,String adultArray,String childArray,
			String breakfastArray,String dateArray) throws EntityNotFoundException, NumberFormatException, ParseException{
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd",
				Locale.ENGLISH);
		long span = Util.daysBetween(datefrom, dateto);
		String subflexiblepackagestring = "";
		String [] date = dateArray.split(",");
		String [] pId = pIdArray.split(",");
		String [] ppn = ppnArray.split(",");
		String [] ucp = ucpArray.split(",");
		String [] extrabed =extrabedArray.split(",");
		String [] adult =adultArray.split(",");
		String [] child =childArray.split(",");
		String [] breakfast =breakfastArray.split(",");
		for(int i=0;i<span;i++){
			long subfpid = new SubFlexiblePackageLogic().EditSubFlexiblePackage(Long.parseLong(pId[i]),
					formatter.parse(date[i]), Double.parseDouble(extrabed[i]), Double.parseDouble(ppn[i]), 
					Double.parseDouble(ucp[i]),Long.parseLong(adult[i]),Long.parseLong(child[i]),
					Boolean.parseBoolean(breakfast[i])).getId();
			subflexiblepackagestring += subfpid + ",";
		}
		return subflexiblepackagestring.substring(0, subflexiblepackagestring.length()-1);
	}
	
	public FlexiblePackage EditFlexiblePackage(long id,long hotelId,String availableForString,
			boolean status,Date datefrom,Date dateto,String description,String packageName,
			String roomtypeString,String subflexiblepackage)
			throws EntityNotFoundException {
		FlexiblePackage t = GetFlexiblePackage(id);
		t.setAvaliableForString(availableForString);
		t.setPackageControl(status);
		t.setDatefrom(datefrom);
		t.setDateto(dateto);
		t.setDescription(description);
		t.setHotelId(hotelId);
		t.setPackageName(packageName);
		t.setRoomtypeString(roomtypeString);
		t.setSubflexiblepackagestring(subflexiblepackage);
		t.setStatus(true);
		t.setAvaliable(true);
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);
		return t;
	}
}
